package com.flow.asyncflow.core.core;


import com.alibaba.fastjson.JSONObject;
import com.flow.asyncflow.core.annotation.FlowInfo;
import com.flow.asyncflow.core.entity.asyncFlowMonitor.QueryAsyncFlowLogRequest;
import com.flow.asyncflow.core.entity.config.AsyncFlowConfigInfo;
import com.flow.asyncflow.core.entity.config.AsyncFlowInfo;
import com.flow.asyncflow.core.entity.core.*;
import com.flow.asyncflow.core.entity.log.asyncflowlog.AsyncFlowLogEntity;
import com.flow.asyncflow.core.entity.log.asyncflowlog.AsyncFlowNodeDetailLogEntity;
import com.flow.asyncflow.core.entity.log.asyncflowlog.AsyncFlowNodeLogEntity;
import com.flow.asyncflow.core.entity.sql.ExecuteSql;
import com.flow.asyncflow.core.enums.ExecuteEnum;
import com.flow.asyncflow.core.node.AsyncFlowBaseGetData;
import com.flow.asyncflow.core.node.AsyncFlowBaseValidator;
import com.flow.asyncflow.core.node.FlowNodeTask;
import com.flow.asyncflow.core.node.IFlowNode;
import com.flow.asyncflow.core.utils.asyncFlowMonitor.AsyncFlowMonitor;
import com.flow.asyncflow.core.utils.beanutils.AsyncFlowBeanUtils;
import com.flow.asyncflow.core.utils.configuration.AsyncFlowConfiguration;
import com.flow.asyncflow.core.utils.log.asyncflowlog.AsyncFlowCommon_Log;
import com.flow.asyncflow.core.utils.log.businesslog.AsyncFlowBusinessLog;
import com.flow.asyncflow.core.utils.msg.AsyncFlowSendMsg;
import com.flow.asyncflow.core.utils.save.BaseSave;
import com.flow.asyncflow.core.utils.threadpool.ThreadPoolExecutorMain;
import lombok.SneakyThrows;
import org.apache.commons.lang.StringUtils;
import org.springframework.boot.CommandLineRunner;
import org.springframework.util.StopWatch;

import java.lang.annotation.Annotation;
import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;


@SuppressWarnings("unchecked")
public abstract class AsyncFlowManager<TReq, TRes extends AsyncFlowResponse, TContext, TReqTypeEnum extends Enum<?>> implements CommandLineRunner {

    /**
     * 流节点集合【普通节点】--各个流内部定义
     */
    // private final LinkedHashMap<ExecuteEnum, LinkedHashMap<IFlowNode, Boolean>> flowNodes = new LinkedHashMap<>();
    private final LinkedHashMap<ExecuteEnum, List<NodeInfo>> flowNodes = new LinkedHashMap<>();
    /**
     * 异步流流信息
     */
    private final AsyncFlowInfo asyncFlowInfo = new AsyncFlowInfo();

    private static AsyncFlowConfigInfo asyncFlowStaticInfo = null;
    /**
     * 节点流线程池
     */
    private static ExecutorService pool = null;

    private final Map<TReqTypeEnum, String> testReqMap = new HashMap<>();
    private AsyncFlowBaseGetData asyncFlowBaseGetData = null;
    //region 初始化

    /**
     * 初始化
     */
    protected AsyncFlowManager() {
        ////加载线程池
        //if (pool == null) {
        //    pool = ThreadPoolExecutorMain.getCustomThreadPoolExecutor();
        //
        //}
        //加载站点配置信息（数据库、环境、报存地址）
        if (asyncFlowStaticInfo == null) {
            AsyncFlowConfiguration autoConfiguration = new AsyncFlowConfiguration();
            Map<String, String> dataBaseInfo = autoConfiguration.getDataBaseInfo();
            asyncFlowStaticInfo = new AsyncFlowConfigInfo();
            //for (Map.Entry<String, String> entry : dataBaseInfo.entrySet()) {
            //    asyncFlowStaticInfo.getDataBaseInfo().put(entry.getKey(), entry.getValue());
            //}
            asyncFlowStaticInfo.setDataBaseInfo(dataBaseInfo);
            asyncFlowStaticInfo.setEvn(autoConfiguration.getEvn());
            asyncFlowStaticInfo.setAppUK(autoConfiguration.getAppUK());
            asyncFlowStaticInfo.setMongoDBConfigStr(autoConfiguration.getMongoDBConfigStr());
            asyncFlowStaticInfo.setMongoDBName(autoConfiguration.getMongoDBName());
            asyncFlowStaticInfo.setEsURL(autoConfiguration.getEsURL());
            asyncFlowStaticInfo.setEsIndexName(autoConfiguration.getEsIndexName());
            asyncFlowStaticInfo.setMongoDBTableName(autoConfiguration.getMongoDBTableName());
            asyncFlowStaticInfo.setNodeArmUrl(autoConfiguration.getNodeArmUrl());
            asyncFlowStaticInfo.setBusinessArmUrl(autoConfiguration.getBusinessArmUrl());
            asyncFlowStaticInfo.setBusinessLogUrl(autoConfiguration.getBusinessLogUrl());
            asyncFlowStaticInfo.setAppUK(autoConfiguration.getAppUK());
            if (autoConfiguration.getCorePoolSize() != null && autoConfiguration.getCorePoolSize() > 0) {
                asyncFlowStaticInfo.setCorePoolSize(autoConfiguration.getCorePoolSize());
                asyncFlowStaticInfo.setMaxPoolSize(autoConfiguration.getMaxPoolSize());
                asyncFlowStaticInfo.setQueueCapacity(autoConfiguration.getQueueCapacity());
                asyncFlowStaticInfo.setThreadNamePrefix(autoConfiguration.getThreadNamePrefix());
                asyncFlowStaticInfo.setKeepAliveSeconds(Long.valueOf(autoConfiguration.getKeepAliveSeconds().toString()));
            }

        }
        //加载当前流信息，名称，负责人等
        if (StringUtils.isBlank(asyncFlowInfo.getFlowName())
                && StringUtils.isBlank(asyncFlowInfo.getFlowMaintainName())
                && asyncFlowInfo.getTimeOutsLimit() == 0) {
            Annotation[] flowInfo = this.getClass().getAnnotations();
            for (Annotation annotation : flowInfo) {
                //获取方法名
                if (annotation instanceof FlowInfo) {
                    asyncFlowInfo.setFlowName(((FlowInfo) annotation).flowName());
                    asyncFlowInfo.setFlowMaintainName(((FlowInfo) annotation).flowMaintainName());
                    asyncFlowInfo.setTimeOutsLimit(((FlowInfo) annotation).timeOutsLimit());
                    asyncFlowInfo.setIgnoreFlowLogEvn(((FlowInfo) annotation).ignoreFlowLogEvn());
                    break;
                }
            }
            asyncFlowInfo.setFlowManagerName(this.getClass().getSimpleName());
            //for (Map.Entry<String, String> entry : asyncFlowStaticInfo.getDataBaseInfo().entrySet()) {
            //    asyncFlowInfo.getDataBaseInfo().put(entry.getKey(), entry.getValue());
            //}
            asyncFlowInfo.setDataBaseInfo(asyncFlowStaticInfo.getDataBaseInfo());
            asyncFlowInfo.setEvn(asyncFlowStaticInfo.getEvn());
            asyncFlowInfo.setAppUK(asyncFlowStaticInfo.getAppUK());
            asyncFlowInfo.setMongoDBConfigStr(asyncFlowStaticInfo.getMongoDBConfigStr());
            asyncFlowInfo.setMongoDBName(asyncFlowStaticInfo.getMongoDBName());
            asyncFlowInfo.setMongoDBTableName(asyncFlowStaticInfo.getMongoDBTableName());
            asyncFlowInfo.setEsURL(asyncFlowStaticInfo.getEsURL());
            asyncFlowInfo.setEsIndexName(asyncFlowStaticInfo.getEsIndexName());
            asyncFlowInfo.setNodeArmUrl(asyncFlowStaticInfo.getNodeArmUrl());
            asyncFlowInfo.setBusinessArmUrl(asyncFlowStaticInfo.getBusinessArmUrl());
            asyncFlowInfo.setBusinessLogUrl(asyncFlowStaticInfo.getBusinessLogUrl());
            if (asyncFlowStaticInfo.getCorePoolSize() != null && asyncFlowStaticInfo.getCorePoolSize() > 0) {
                asyncFlowInfo.setCorePoolSize(asyncFlowStaticInfo.getCorePoolSize());
                asyncFlowInfo.setMaxPoolSize(asyncFlowStaticInfo.getMaxPoolSize());
                asyncFlowInfo.setQueueCapacity(asyncFlowStaticInfo.getQueueCapacity());
                asyncFlowInfo.setThreadNamePrefix(asyncFlowStaticInfo.getThreadNamePrefix());
                asyncFlowInfo.setKeepAliveSeconds(Long.valueOf(asyncFlowStaticInfo.getKeepAliveSeconds().toString()));
            }

        }
        //加载线程池
        if (pool == null) {
            pool = ThreadPoolExecutorMain.getCustomThreadPoolExecutor(asyncFlowInfo);

        }
        //初始化记录上下文节点
        if (asyncFlowBaseGetData == null) {
            asyncFlowBaseGetData = new AsyncFlowBaseGetData();
        }
    }
    //endregion


    //region 添加节点到执行流中

    /**
     * 添加普通节点
     *
     * @param executeEnum 操作类型
     * @param flowNode    带具体类型的操作节点
     * @param isCanAsync  是否异步
     */
    @SneakyThrows
    protected void addFlowNode(ExecuteEnum executeEnum, IFlowNode flowNode, boolean isCanAsync, Enum<?>... operatorEnum) {

        //LinkedHashMap<IFlowNode, Boolean> nodes = flowNodes.get(executeEnum);
        //去除公共查询的概念
        //if (executeEnum == ExecuteEnum.GetDataPub) {
        //    executeEnum = ExecuteEnum.GetData;
        //}
        List<NodeInfo> nodes = flowNodes.computeIfAbsent(executeEnum, k -> new ArrayList<>());
        Enum<?> thisOperatorEnum = null;
        if (operatorEnum.length > 0) {
            thisOperatorEnum = operatorEnum[0];
        }
        if (flowNode == null || containsKey(nodes, flowNode, thisOperatorEnum)) {
            return;
        }
        NodeInfo nodeInfo;
        nodeInfo = new NodeInfo();
        if (executeEnum == ExecuteEnum.Async) {
            isCanAsync = true;
        }
        if (operatorEnum.length > 0) {

            nodeInfo.setOperatorEnum(operatorEnum[0]);
//            //设置当前节点的可执行枚举
//            Field field = flowNode.getClass().getField("operatorEnumList");
//            field.setAccessible(true);
//            Field modifiers = Field.class.getDeclaredField("modifiers");
//            modifiers.setAccessible(true);
//            modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);//fianl标志位置0
//            field.set(flowNode, nodeInfo.setOperatorEnum(operatorEnum[0]));
        }

        nodeInfo.setIFlowNode(flowNode);
        nodeInfo.setCanAsync(isCanAsync);

        nodes.add(nodeInfo);
        //nodes.put(flowNode, isCanAsync);
    }

    /**
     * 判断当前类是否添加过
     *
     * @param nodes    已经添加的节点
     * @param flowNode 当前需要添加的节点
     * @return 是否添加过
     */
    private boolean containsKey(List<NodeInfo> nodes, IFlowNode flowNode, Enum<?> thisOperatorEnum) {
        //for (Map.Entry<IFlowNode, Boolean> entry : nodes.entrySet()) {
        //    if (entry.getKey().getClass().equals(flowNode.getClass())) {
        //        return true;
        //    }
        //
        //}
        for (NodeInfo node : nodes) {
            if (node.getIFlowNode().getClass().equals(flowNode.getClass())) {
                //node.getOperatorEnum() == null 说明是公共节点，存在一个公共的节点，则不添加特定节点
                if (node.getOperatorEnum() == null) {
                    return true;
                } else {
                    //本次添加的是公共节点，并且历史存在特定节点，将特定节点更新为公共节点
                    if (thisOperatorEnum == null) {
                        node.setOperatorEnum(null);
                    } else {
                        //存在相同操作枚举的则不进行添加
                        if (node.getOperatorEnum().equals(thisOperatorEnum)) {
                            return true;
                        }
                    }
                }
            }
        }
        return false;
    }

    //endregion

    /**
     * 设置测试数据
     *
     * @param testStr 测试数据
     */
    protected void addTestStr(String testStr, TReqTypeEnum reqTypeEnum) {
        if (StringUtils.isNotBlank(testStr)) {
            testReqMap.put(reqTypeEnum, testStr);
        }
    }
    //region 执行节点

    //region 执行节点【带耗时明细】

    /**
     * 执行节点【带耗时明细】
     *
     * @param executeEnum      操作类型
     * @param asyncFlowRequest 上下文
     * @param asyncFlowData    请求参数
     * @return AsyncFlowNodeResponse
     */
    private AsyncFlowNodeResponse exeNode(ExecuteEnum executeEnum, AsyncFlowRequest asyncFlowRequest, AsyncFlowContext asyncFlowData, LinkedHashMap<ExecuteEnum, Long> timeConsuming, AsyncFlowResponse response, boolean allNodeIsSuccess) {
        AsyncFlowNodeResponse asyncFlowNodeResponse;
        //如果是测试调用，对于验证和查询数据库，数据源直接跳过
        if (asyncFlowData.getAsyncFlowInfo().isTest() && (executeEnum == ExecuteEnum.Validator || executeEnum == ExecuteEnum.GetData)) {
            return new AsyncFlowNodeResponse(200, "成功");
        }
        if (executeEnum == ExecuteEnum.Async) {
            pool.execute(() -> {
                exeNode(ExecuteEnum.Async, asyncFlowRequest, asyncFlowData);
                AsyncFlowBusinessLog.saveBusinessLog(asyncFlowRequest, asyncFlowData, response.getMsg(), allNodeIsSuccess);
                //执行顺序 验证-->查询-->操作-->保存-->同步-->异步
                //当执行的操作是异步时，表示当前流所有的操作已经执行完成
                AsyncFlowCommon_Log.SaveExecuteTrackLogs(asyncFlowRequest, asyncFlowData, response, timeConsuming, allNodeIsSuccess, asyncFlowInfo);
            });

            return new AsyncFlowNodeResponse(200, "成功");
        }
        StopWatch sw = new StopWatch();
        sw.start(executeEnum.getMsg() + "-开始");
        asyncFlowNodeResponse = exeNode(executeEnum, asyncFlowRequest, asyncFlowData);
        sw.stop();
        long time = sw.getTotalTimeMillis();
        if (timeConsuming.containsKey(executeEnum)) {
            time = timeConsuming.get(executeEnum) + sw.getTotalTimeMillis();
        }
        timeConsuming.put(executeEnum, time);
        return asyncFlowNodeResponse;
    }


    //endregion

    //region 执行节点【基础执行】

    /**
     * 执行节点
     *
     * @param executeEnum      操作类型
     * @param asyncData        上下文
     * @param asyncFlowRequest 请求参数
     * @return AsyncFlowNodeResponse
     * @author lgq07612
     **/
    private AsyncFlowNodeResponse exeNode(ExecuteEnum executeEnum, AsyncFlowRequest asyncFlowRequest, AsyncFlowContext asyncData) {
        AsyncFlowNodeResponse asyncFlowNodeResponse = new AsyncFlowNodeResponse(200, "成功");
        List<Future<AsyncFlowNodeResponse>> futureList = new ArrayList<>();
        //LinkedHashMap<IFlowNode, Boolean> nodes = flowNodes.get(executeEnum);
        List<NodeInfo> nodes = flowNodes.get(executeEnum);
        if (nodes != null && asyncData.getOperatorEnum() != null) {
            nodes = nodes.stream().filter(c -> c.getOperatorEnum() == null || (asyncData.getOperatorEnum().equals(c.getOperatorEnum()))).collect(Collectors.toList());
        }
        //执行查询时将公共查询一起执行
        //if (executeEnum == ExecuteEnum.GetData) {
        //
        //    List<NodeInfo> pubNodes = flowNodes.get(ExecuteEnum.GetDataPub);
        //    if (pubNodes != null && !pubNodes.isEmpty()) {
        //        if (nodes == null) {
        //            nodes = new ArrayList<>();
        //        }
        //        for (NodeInfo pubNode : pubNodes) {
        //            addFlowNode(ExecuteEnum.GetData, pubNode.getIFlowNode(), pubNode.isCanAsync());
        //        }
        //    }
        //
        //}
        if (nodes == null || nodes.isEmpty()) {
            return asyncFlowNodeResponse;
        }
        for (NodeInfo node : nodes) {
            StopWatch sw3 = new StopWatch();
            sw3.start(executeEnum.getMsg() + "-开始");
            //需要异步执行
            if (node.isCanAsync() || executeEnum == ExecuteEnum.Async) {
                futureList.add(pool.submit(new FlowNodeTask(node.getIFlowNode(), asyncFlowRequest, asyncData, node.isCanAsync(), asyncFlowInfo, executeEnum)));
            } else {
                //异步执行集合里面还有未执行完成的任务
                asyncFlowNodeResponse = getTaskListFuture(executeEnum, asyncFlowRequest, futureList);
                if (asyncFlowNodeResponse.getCode() != 200 || asyncFlowNodeResponse.isBreakOff()) {
                    return asyncFlowNodeResponse;
                }
                futureList = new ArrayList<>();
                asyncFlowNodeResponse = new FlowNodeTask(node.getIFlowNode(), asyncFlowRequest, asyncData, node.isCanAsync(), asyncFlowInfo, executeEnum).flowNodeTaskExecute();
                if (asyncFlowNodeResponse.getCode() != 200 || asyncFlowNodeResponse.isBreakOff()) {
                    return asyncFlowNodeResponse;
                }
            }

        }
        asyncFlowNodeResponse = getTaskListFuture(executeEnum, asyncFlowRequest, futureList);
        return asyncFlowNodeResponse;
    }

    //endregion

    //region 获取异步集合的结果

    /**
     * 获取异步集合的结果
     *
     * @param executeEnum 执行类型
     * @param futureList  集合
     * @return 节点返回
     */
    private AsyncFlowNodeResponse getTaskListFuture(ExecuteEnum executeEnum, AsyncFlowRequest asyncFlowRequest, List<Future<AsyncFlowNodeResponse>> futureList) {
        AsyncFlowNodeResponse asyncFlowNodeResponse = new AsyncFlowNodeResponse(200, "成功");
        if (futureList == null || futureList.size() == 0) {
            return asyncFlowNodeResponse;
        }
        for (Future<AsyncFlowNodeResponse> future : futureList) {
            try {
                asyncFlowNodeResponse = future.get(120, TimeUnit.SECONDS);
            } catch (TimeoutException | InterruptedException | ExecutionException e) {
                future.cancel(true);
                asyncFlowNodeResponse.setCode(-100);
                asyncFlowNodeResponse.setMsg("获取线程执行结果异常");
                String s = AsyncFlowSendMsg.buildErrorMsg(asyncFlowRequest, e, "获取异步线程执行的结果【" + executeEnum.getMsg() + "】", asyncFlowInfo);
                AsyncFlowSendMsg.sendQYWXMsg(asyncFlowInfo.getFlowMaintainName(), s, asyncFlowInfo.getNodeArmUrl());
            }
            //只有在非异步操作是需要跳出（异步操作之间互不影响，异步操作的失败，不影响后面的异步操作）
            if (executeEnum != ExecuteEnum.Async && (asyncFlowNodeResponse.getCode() != 200 || asyncFlowNodeResponse.isBreakOff())) {
                return asyncFlowNodeResponse;
            }
        }

        return asyncFlowNodeResponse;
    }
    //endregion

    //endregion


    //region 本地测试时构建测试数据

    /**
     * 构建测试数据
     *
     * @param asyncFlowData 上下文
     */
    private void buildTestData(AsyncFlowContext asyncFlowData, TReqTypeEnum reqTypeEnum) {

        if ((asyncFlowData.getAsyncFlowInfo().getEvn().equals("test") || asyncFlowData.getAsyncFlowInfo().getEvn().equals("qa"))) {

            String thisTestReqStr = testReqMap.get(reqTypeEnum);
            if (StringUtils.isBlank(thisTestReqStr)) {
                return;
            }
            AsyncFlowLogEntity appInfo;
            QueryAsyncFlowLogRequest queryAsyncFlowLogRequest = new QueryAsyncFlowLogRequest();
            queryAsyncFlowLogRequest.setTrackGuid(thisTestReqStr);
            List<AsyncFlowLogEntity> asyncFlowLogEntityList = new AsyncFlowMonitor().getAsyncFlowLogEs(queryAsyncFlowLogRequest, null);
            appInfo = asyncFlowLogEntityList.get(0);

            AsyncFlowNodeLogEntity asyncFlowNodeLogEntity = appInfo.getAsyncFlowNodeLogEntityList().stream().filter(c -> c.getExecuteEnumCode() == ExecuteEnum.GetData.getCode() && c.getLogFileName().equals("AsyncFlowBaseGetData")).findFirst().orElse(null);

            if (asyncFlowNodeLogEntity != null && asyncFlowNodeLogEntity.getAsyncFlowNodeDetailLogEntityList() != null) {
                AsyncFlowNodeDetailLogEntity asyncFlowNodeDetailLogEntity = asyncFlowNodeLogEntity.getAsyncFlowNodeDetailLogEntityList().stream().filter(c -> c.getLogFileName().equals("AsyncFlowBaseGetData")).findFirst().orElse(null);
                if (asyncFlowNodeDetailLogEntity != null) {
                    //Map<? extends String, ?> reqMap = (Map<? extends String, ?>) ;
                    JSONObject reqMap = JSONObject.parseObject(asyncFlowNodeDetailLogEntity.getResponse().toString());
                    //删除枚举
                    reqMap.remove(reqTypeEnum.getClass().getName());
                    asyncFlowData.getDataSourceMap().putAll(reqMap);
                    asyncFlowData.getAsyncFlowInfo().setTest(true);
                }
            }


        }

    }
    //endregion

    //region 注入执行流、设置返回参数【子类重写】

    /**
     * 注入执行计划
     */
    protected abstract void managerStartup();


    //endregion

    //region 执行异步流


    public TRes exec(TReq request, TReqTypeEnum reqTypeEnum) {

        TRes response = null;
        Class<TRes> clazzRes;
        Class<TContext> clazzContext;
        ParameterizedType parameterizedType = (ParameterizedType) this.getClass().getGenericSuperclass();
        if (parameterizedType.getActualTypeArguments().length == 4) {
            clazzRes = (Class<TRes>) parameterizedType.getActualTypeArguments()[1];
            clazzContext = (Class<TContext>) parameterizedType.getActualTypeArguments()[2];
            response = exec(request, reqTypeEnum, clazzRes, clazzContext);
        }
        return response;
    }

    /**
     * 执行异步流
     */
    public TRes exec(TReq request, TReqTypeEnum reqTypeEnum, Class<TRes> clazzRes, Class<TContext> clazzContext) {

        AsyncFlowRequest asyncFlowRequest = new AsyncFlowRequest();
        AsyncFlowResponse asyncFlowResponse = new AsyncFlowResponse();
        AsyncFlowContext asyncFlowData = new AsyncFlowContext();
        asyncFlowData.setOperatorEnum(reqTypeEnum);
        TRes response;
        AsyncFlowNodeResponse asyncFlowNodeResponse;
        boolean allNodeIsSuccess = false;
        //=======每个步骤（验证、查询、操作、保存、同步、异步）的耗时明细==============
        LinkedHashMap<ExecuteEnum, Long> timeConsuming = new LinkedHashMap<>();
        //=======每个步骤（验证、查询、操作、保存、同步、异步）的执行结果，默认是成功（200：成功，其他：失败）==============
        int validateCode = 200, getDataCode = 200, operatorCode = 200, customSaveCode = 200, baseSaveCode = 200, syncCode = 200;
        String nodeErrorMsg = "";
        //======构建上下文AsyncFlowPlusDataSlot和请求参数AsyncFlowRequest==================
        new AsyncFlowBaseValidator().buildAsyncFlowRequestAndContext(asyncFlowRequest, asyncFlowData, request, clazzRes, reqTypeEnum, clazzContext, asyncFlowInfo, timeConsuming);
        asyncFlowRequest = asyncFlowData.getAsyncFlowRequest(AsyncFlowRequest.class);
        response = asyncFlowData.getResponse(clazzRes);
        //asyncFlowData.setThisMangerClass(this.getClass());
        //================构建本地测试数据=============
        buildTestData(asyncFlowData, reqTypeEnum);
        //===================验证====================
        asyncFlowNodeResponse = exeNode(ExecuteEnum.Validator, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowResponse, false);
        validateCode = asyncFlowNodeResponse.getCode();
        //兼容老版本的写法，请求参数中父类AsyncFlowRequest的属性没有赋值
        //setRequestInfo(asyncFlowData, request);
        if (validateCode != 200) {
            //验证执行错误信息
            nodeErrorMsg = asyncFlowNodeResponse.getMsg();
        }
        //===================查询====================
        //table.get(ExecuteEnum.Validator,200)!=null--当前table中存在操作类型为 验证 执行结果为 200 的执行结果Msg
        if (validateCode == 200 && !asyncFlowNodeResponse.isBreakOff()) {
            asyncFlowNodeResponse = exeNode(ExecuteEnum.GetData, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowResponse, false);
            getDataCode = asyncFlowNodeResponse.getCode();
            if (getDataCode != 200) {
                //验证执行错误信息
                nodeErrorMsg = asyncFlowNodeResponse.getMsg();
            }
            //===================操作====================
            if (getDataCode == 200) {
                asyncFlowNodeResponse = exeNode(ExecuteEnum.Operator, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowResponse, false);
                operatorCode = asyncFlowNodeResponse.getCode();
                if (operatorCode != 200) {
                    //操作执行错误信息
                    nodeErrorMsg = asyncFlowNodeResponse.getMsg();
                }
                //===================保存====================
                if ((operatorCode == 200 && !asyncFlowNodeResponse.isBreakOff() && asyncFlowData.getExecuteSQLs().size() > 0) || asyncFlowData.getExecuteSQLs().stream().anyMatch(ExecuteSql::isMustExecute)) {
                    asyncFlowNodeResponse = new BaseSave().execute(asyncFlowRequest, asyncFlowData, operatorCode, asyncFlowInfo, timeConsuming);
                    baseSaveCode = asyncFlowNodeResponse.getCode();
                    if (baseSaveCode != 200) {
                        //操作执行错误信息
                        nodeErrorMsg = StringUtils.isNotBlank(nodeErrorMsg) ? nodeErrorMsg + "|" + asyncFlowNodeResponse.getMsg() : asyncFlowNodeResponse.getMsg();
                    }
                    if (baseSaveCode == 200) {
                        asyncFlowNodeResponse = exeNode(ExecuteEnum.Save, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowResponse, false);
                        customSaveCode = asyncFlowNodeResponse.getCode();
                        if (customSaveCode != 200) {
                            //操作执行错误信息
                            nodeErrorMsg = StringUtils.isNotBlank(nodeErrorMsg) ? nodeErrorMsg + "|" + asyncFlowNodeResponse.getMsg() : asyncFlowNodeResponse.getMsg();
                        }
                    }
                    //===================同步====================
                    if (operatorCode == 200 && customSaveCode == 200 && baseSaveCode == 200) {
                        asyncFlowNodeResponse = exeNode(ExecuteEnum.Sync, asyncFlowRequest, asyncFlowData, timeConsuming, asyncFlowResponse, false);
                        syncCode = asyncFlowNodeResponse.getCode();
                        if (syncCode != 200) {
                            //操作执行错误信息
                            nodeErrorMsg = nodeErrorMsg + asyncFlowNodeResponse.getMsg() + "|";
                        }
                    }
                }
            }
        }
        //=================设置异步流执行结果================
        asyncFlowResponse.setCode(asyncFlowNodeResponse.getCode());
        if (validateCode == 200 && getDataCode == 200 && operatorCode == 200 && baseSaveCode == 200 && customSaveCode == 200 && syncCode == 200) {
            allNodeIsSuccess = true;
            asyncFlowResponse.setMsg("成功");
        } else {
            asyncFlowResponse.setMsg(nodeErrorMsg);
            if (validateCode == -1 || getDataCode == -1 || operatorCode == -1 || syncCode == -1 || baseSaveCode == -1 || customSaveCode == -1) {
                asyncFlowResponse.setMsg("系统异常");
            }
        }
        //======设置AsyncFlowResponse节点流的返回参数到上下文数据槽中、设置节点的返回==================
        asyncFlowData.setAsyncFlowResponse(asyncFlowResponse);
        //如果节点最终的执行接口不是成功的 将返回参数重置成初始值
        if (asyncFlowResponse.getCode() != 200) {
            try {
                response = clazzRes.newInstance();
            } catch (IllegalAccessException | InstantiationException ignored) {
            }
        }
        response = asyncFlowData.getResponse(clazzRes);
        response.setMsg(asyncFlowResponse.getMsg());
        response.setCode(asyncFlowResponse.getCode());
        //===================异步====================
        //最后一步异步执行里面会记录请求参数，所以这边的asyncFlowRequest 用传入的接口参数
        exeNode(ExecuteEnum.Async, asyncFlowRequest, asyncFlowData, timeConsuming, response, allNodeIsSuccess);

        return response;
    }


    //endregion

    @Override
    @SneakyThrows
    public void run(String... args) {
        managerStartup();
        //在查下操作的最后添加一个记录上下文的 操作，当前操作只有在预发或者本地测试环境才会执行
        if (asyncFlowInfo.getEvn().equals("stage") || asyncFlowInfo.getEvn().equals("test")) {
            addFlowNode(ExecuteEnum.GetData, asyncFlowBaseGetData, false);
        }


    }
}
